package com.shunli.cterminal.model.dto;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.examples.core.exception.ServiceException;
import com.shunli.cterminal.enums.TimeTypeEnum;
import com.shunli.cterminal.model.code.CterminalResultCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 描述
 * </p>
 *
 * @author daodao
 * @since 2025-04-29 17:05
 */
@Data
public class PolicyTimeJsonDTO implements Serializable {
    private static final long serialVersionUID = -8724795874147330936L;

    /**
     * 时间类型 0-时间段 1-日期 2-节假日(暂无) 3-星期
     */
    @Schema(description = "时间类型 0-时间段 1-日期 2-节假日(暂无) 3-星期")
    private String timeType;
    @Schema(description = "时间区间")
    private List<PolicyTimeInterval> timeInterval;

    // 默认
    public static String getDefaultPolicyTimeJson() {
        PolicyTimeJsonDTO policyTimeJsonDTO = new PolicyTimeJsonDTO();
        policyTimeJsonDTO.setTimeType(TimeTypeEnum.DATA_TIME.getCode());
        policyTimeJsonDTO.setTimeInterval(new ArrayList<>());
        PolicyTimeInterval policyTimeInterval = new PolicyTimeInterval();
        policyTimeInterval.setStartInterval("00:00:00");
        policyTimeInterval.setEndInterval("23:59:59");
        policyTimeJsonDTO.getTimeInterval().add(policyTimeInterval);
        return JSONObject.toJSONString(policyTimeJsonDTO);
    }

    /**
     * 参数校验
     *
     * @param policyTimeJsonDTO 参数
     * @return boolean
     */
    public static void checkParams(PolicyTimeJsonDTO policyTimeJsonDTO) {
        if (ObjectUtil.isNull(policyTimeJsonDTO)) {
            throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
        }
        if (ObjectUtil.isNull(policyTimeJsonDTO.getTimeType())) {
            throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
        }
        if (CollectionUtil.isEmpty(policyTimeJsonDTO.getTimeInterval())) {
            throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
        }

        if (StrUtil.equals(TimeTypeEnum.DATA_TIME.getCode(), policyTimeJsonDTO.getTimeType())) {
            checkDataTime(policyTimeJsonDTO.getTimeInterval());
        } else if (StrUtil.equals(TimeTypeEnum.DATA.getCode(), policyTimeJsonDTO.getTimeType())) {
            checkData(policyTimeJsonDTO.getTimeInterval());
        } else if (StrUtil.equals(TimeTypeEnum.HOLIDAYS.getCode(), policyTimeJsonDTO.getTimeType())) {
            // 节假日暂无校验
            throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
        } else if (StrUtil.equals(TimeTypeEnum.WEEK.getCode(), policyTimeJsonDTO.getTimeType())) {
            checkWeek(policyTimeJsonDTO.getTimeInterval());
        }
    }

    public static void checkDataTime(List<PolicyTimeInterval> policyTimeJsonDTO) {
        for (int i = 0; i < policyTimeJsonDTO.size() - 1; i++) {
            PolicyTimeInterval policyTimeInterval = policyTimeJsonDTO.get(i);
            if (StrUtil.hasBlank(policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval())) {
                throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
            }
            LocalTime startTime = LocalTime.parse(policyTimeInterval.getStartInterval());
            LocalTime endTime = LocalTime.parse(policyTimeInterval.getEndInterval());
            if (!startTime.isBefore(endTime) || startTime.equals(endTime)) {
                throw new ServiceException(CterminalResultCode.ACTIVITY_START_TIME_AFTER_END);
            }

            for (int j = i + 1; j < policyTimeJsonDTO.size(); j++) {
                PolicyTimeInterval policyTimeIntervalItem = policyTimeJsonDTO.get(j);
                LocalTime targetStartTime = LocalTime.parse(policyTimeIntervalItem.getStartInterval());
                LocalTime targetEndTime = LocalTime.parse(policyTimeIntervalItem.getEndInterval());
                boolean isInRangeStartTime = (targetStartTime.isAfter(startTime) && targetStartTime.isBefore(endTime)) || targetStartTime.equals(startTime);
                boolean isInRangeEndTime = (targetEndTime.isAfter(startTime) && targetEndTime.isBefore(endTime)) || targetEndTime.equals(endTime);
                if (isInRangeStartTime || isInRangeEndTime) {
                    String message = StrUtil.format("[{},{}] 和 [{},{}] 规则时间重叠", policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval(), policyTimeIntervalItem.getStartInterval(), policyTimeIntervalItem.getEndInterval());
                    throw new ServiceException(CterminalResultCode.GENERIC_CUSTOM_ERROR_MESSAGE, message);
                }
            }
        }
    }

    public static void checkData(List<PolicyTimeInterval> policyTimeJsonDTO) {
        for (int i = 0; i < policyTimeJsonDTO.size() - 1; i++) {
            PolicyTimeInterval policyTimeInterval = policyTimeJsonDTO.get(i);
            if (StrUtil.hasBlank(policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval())) {
                throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
            }
            LocalDate startTime = LocalDate.parse(policyTimeInterval.getStartInterval());
            LocalDate endTime = LocalDate.parse(policyTimeInterval.getEndInterval());
            if (!startTime.isBefore(endTime) || startTime.equals(endTime)) {
                throw new ServiceException(CterminalResultCode.ACTIVITY_START_TIME_AFTER_END);
            }

            for (int j = i + 1; j < policyTimeJsonDTO.size(); j++) {
                PolicyTimeInterval policyTimeIntervalItem = policyTimeJsonDTO.get(j);
                LocalDate targetStartTime = LocalDate.parse(policyTimeIntervalItem.getStartInterval());
                LocalDate targetEndTime = LocalDate.parse(policyTimeIntervalItem.getEndInterval());
                boolean isInRangeStartTime = (targetStartTime.isAfter(startTime) && targetStartTime.isBefore(endTime)) || targetStartTime.equals(startTime);
                boolean isInRangeEndTime = (targetEndTime.isAfter(startTime) && targetEndTime.isBefore(endTime)) || targetEndTime.equals(endTime);
                if (isInRangeStartTime || isInRangeEndTime) {
                    String message = StrUtil.format("[{},{}] 和 [{},{}] 规则时间重叠", policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval(), policyTimeIntervalItem.getStartInterval(), policyTimeIntervalItem.getEndInterval());
                    throw new ServiceException(CterminalResultCode.GENERIC_CUSTOM_ERROR_MESSAGE, message);
                }
            }
        }
    }


    public static void checkWeek(List<PolicyTimeInterval> policyTimeJsonDTO) {
        for (int i = 0; i < policyTimeJsonDTO.size() - 1; i++) {
            PolicyTimeInterval policyTimeInterval = policyTimeJsonDTO.get(i);
            if (StrUtil.hasBlank(policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval())
                    || ObjectUtil.hasNull(policyTimeInterval.getWeek())) {
                throw new ServiceException(CterminalResultCode.PARAMS_EMPTY);
            }
            LocalTime startTime = LocalTime.parse(policyTimeInterval.getStartInterval());
            LocalTime endTime = LocalTime.parse(policyTimeInterval.getEndInterval());
            if (!startTime.isBefore(endTime) || startTime.equals(endTime)) {
                throw new ServiceException(CterminalResultCode.ACTIVITY_START_TIME_AFTER_END);
            }

            for (int j = i + 1; j < policyTimeJsonDTO.size(); j++) {
                PolicyTimeInterval policyTimeIntervalItem = policyTimeJsonDTO.get(j);
                if (policyTimeInterval.getWeek().equals(policyTimeIntervalItem.getWeek())) {
                    LocalTime targetStartTime = LocalTime.parse(policyTimeIntervalItem.getStartInterval());
                    LocalTime targetEndTime = LocalTime.parse(policyTimeIntervalItem.getEndInterval());
                    boolean isInRangeStartTime = (targetStartTime.isAfter(startTime) && targetStartTime.isBefore(endTime)) || targetStartTime.equals(startTime);
                    boolean isInRangeEndTime = (targetEndTime.isAfter(startTime) && targetEndTime.isBefore(endTime)) || targetEndTime.equals(endTime);
                    if (isInRangeStartTime || isInRangeEndTime) {
                        String message = StrUtil.format("[{},{}] 和 [{},{}] 规则时间重叠", policyTimeInterval.getStartInterval(), policyTimeInterval.getEndInterval(), policyTimeIntervalItem.getStartInterval(), policyTimeIntervalItem.getEndInterval());
                        throw new ServiceException(CterminalResultCode.GENERIC_CUSTOM_ERROR_MESSAGE, message);
                    }
                }
            }
        }
    }

    /**
     * 价格区间
     */
    @Data
    public static class PolicyTimeInterval implements Serializable {
        private static final long serialVersionUID = -5054144170515893367L;
        @Schema(description = "星期 1,2,3,4,5,6,7")
        private Integer week;
        @Schema(description = "开始时间")
        private String startInterval;
        @Schema(description = "结束时间")
        private String endInterval;
    }
}
